from random import random, randint
import os
import time

from flask import Blueprint, request, Response

from config import REDIS_IMG_CODE_KEY, REDIS_MSG_CODE_KEY, MD5_SALT
from db_init import db
from model import User
from cache import redis_cli
from tools.tools import create_img, my_route, item2dict
import string
from my_celery.tasks.celery_task import send_code
from hashlib import md5
from flask_login import login_user, login_required, logout_user, current_user
from flask_siwadoc import BaseModel
# from tools.swagger_tools import NewBlueprint as Blueprint
# from kafka_init import producer, consumer, kafka_cli
from swaager_init import siwa
from kafka import KafkaConsumer

users = siwa.blueprint('/user', __name__)


@users.route('/info', methods=['get'])
@login_required
def info():
    return my_route(200, item2dict(current_user, filter=['pwd']))


class RegisterJson(BaseModel):
    name: str
    pwd: str
    phone: str
    img: str
    landlord: bool = False
    code: str


@users.route('/register', methods=['POST'])
def register():
    data = request.json
    code = data.pop('code')
    if code != redis_cli.get(REDIS_MSG_CODE_KEY + data.get("phone")).decode('utf-8'):
        return my_route(204)

    data['pwd'] = md5(data['pwd'].encode() + MD5_SALT).hexdigest()
    user = User(**data)
    db.session.add(User(**data))
    db.session.commit()

    # 删除redis里的验证码
    redis_cli.delete(REDIS_IMG_CODE_KEY + data["phone"])

    return my_route(200, item2dict(user))


@users.route('/imgcode', methods=['get'])
def get_imgcode():
    phone = request.args.get('phone')

    code = [string.ascii_lowercase[randint(0, 25)] for _ in range(4)]
    img = create_img(code)
    redis_cli.set(REDIS_IMG_CODE_KEY + phone, ''.join(code))
    return Response(img.getvalue(), mimetype="image/jpeg")


@users.route('/message', methods=['get'])
def message():
    code = request.args.get('code')
    phone = request.args.get('phone')
    # if code != redis_cli.get(REDIS_IMG_CODE_KEY + phone).decode('utf-8'):
    #     return {"code": 204, "msg": "验证码错误"}

    # 线程任务
    from threading import Thread
    Thread(target=send_code, args=(phone,)).start()
    # celery 异步任务
    # send_code.delay(phone)
    # # 荣联运短信认证 给手机号发验证码
    # 验证码存redis 超时时间1分钟

    # 删除redis里的验证码
    # redis_cli.delete(REDIS_IMG_CODE_KEY + phone)

    return {"code": 200, "msg": "创建成"}


@users.route('/get_code', methods=['get'])
def gc():
    time.sleep(10)
    return {'data': 234234}


@users.route('/avatar', methods=['post'])
def avatar():
    img = request.files.get('img')
    uid = request.form.get('u_id')

    # 文件存储
    file_path = f'./static/images/{uid}'
    if not os.path.exists(file_path):
        os.mkdir(path=file_path)
    img.save(f'{file_path}/{img.filename}')

    User.query.filter_by(id=uid).update({'img': img.filename})
    db.session.commit()
    return {'data': 234234}


@users.route('/BreakpointAvatar', methods=['post'])
def breakpoin_avatar():
    data = request.json
    # 文件存储
    file_path = f'./static/images/{data.get("uid")}'
    if not os.path.exists(file_path):
        os.mkdir(path=file_path)
    with open(os.path.join(file_path, f"{data['bytes_change'] + data['file_name']}"), 'wb') as f:
        f.write(data['data'].encode('utf-8'))

    # 文件整合
    if data['max_change'] == int(data['bytes_change'].split('-')[-1]):
        dirs = list(filter(lambda x: data['file_name'] in x, os.listdir(file_path)))

        for f_name in sorted(dirs):
            old_file_path = os.path.join(file_path, f_name)
            with open(os.path.join(file_path, data['file_name']), 'ab') as f:
                old_file = open(old_file_path, 'rb')
                f.write(old_file.read())
            old_file.close()

            #  删除旧文件
            os.remove(old_file_path)

    return {'data': 234234}


@users.route('/BreakpointAvatar', methods=['get'])
def get_breakpoin_avatar():
    data = request.json
    # 文件存储
    file_path = f'./static/images/{data.get("uid")}'
    dirs = os.listdir(file_path)

    return list(filter(lambda x: data['file_name'] in x, dirs))


@users.route('/login', methods=['POST'])
def login():
    phone = request.form.get('phone')
    pwd = request.form.get('pwd')
    user = User.query.filter_by(phone=phone).first()
    if user and user.pwd == md5(pwd.encode() + MD5_SALT).hexdigest():
        login_user(user)
        return my_route(200, item2dict(user))

    return my_route(206)


@users.route('/logout', methods=['GET'])
@login_required
def logout():
    print(current_user.id)
    logout_user()
    return my_route(200)


@users.route('/chat', methods=['post'])
@login_required
def chat_send():
    msg = request.json.get('msg').encode('utf-8')
    topic = request.json.get('topic')
    producer.send(topic, msg)
    return my_route(200)


@users.route('/chat', methods=['get'])
@login_required
def chat_read():
    topic = request.args.get('topic')
    consumer = KafkaConsumer(topic, group_id='chat')
    value = next(consumer).value.decode('utf-8')
    consumer.close()
    return my_route(200, {'data': value})


@users.route('/chat/group', methods=['post'])
@login_required
def add_topic():
    send_id = request.args.get('send_id')
    topic = '_'.join(sorted([send_id, str(current_user.id)]))
    producer.send(topic, b'')
    return my_route(200, data={'topic': topic})


@users.route('/chat/back', methods=['get'])
@login_required
def chat_back_read():
    topic = request.args.get('topic')
    consumer = KafkaConsumer(topic, group_id='back')
    value = next(consumer).value.decode('utf-8')
    consumer.close()
    return my_route(200, {'data': value})
